package com.lzp.utils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * @author : lzp
 * @version 1.0
 * @date : 2022/1/6 16:22
 * @apiNote : TODO
 */
public class FileUtils {
    /**
     * @param filePathList
     * @param targetPath
     * @throws IOException
     */
    public static void zipFile(List<String> filePathList,String targetPath) throws IOException {
        //新建目标路径文件夹
        File targetDirectory = new File(new File(targetPath).getParent());
        if (!targetDirectory.exists()){
            targetDirectory.mkdirs();
        }
        ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(targetPath)));
        for (String filePath : getDirectoryFile(filePathList)) {
            //String fileName = filePath.substring(filePath.lastIndexOf(File.separator)+1);
            File file = new File(filePath);
            if (!file.exists()){
                System.out.println(filePath+"路径文件不存在!");
                continue;
            }
            if (file.isDirectory()){
                file.listFiles();
            }
            //todo 不同文件夹下的文件名可能有重复的问题
            ZipEntry zipEntry = new ZipEntry(file.getName());
            zos.putNextEntry(zipEntry);
            BufferedInputStream fis = new BufferedInputStream(new FileInputStream(filePath));
            byte[] bytes=new byte[2048];
            int len;
            while((len=fis.read(bytes))!=-1) {
                //从源文件读出，往压缩文件中写入
                zos.write(bytes,0,len);
            }
            zos.closeEntry();
            fis.close();
        }
        zos.close();
    }

    /**todo 多个压缩包文件名重复问题
     *  多个压缩文件处于同一文件夹下统一解压的问题
     * @param zipFiles
     * @param targetPathDirectory
     * @throws IOException
     */
    public static void unZipFile(List<String> zipFiles,String targetPathDirectory) throws IOException {
        File file = new File(targetPathDirectory);
        boolean flag=false;
        if (!file.exists()){
            file.mkdirs();
            flag=true;
        }
        if (!file.isDirectory()){
            if (flag) {
                file.delete();
            }
            throw new IOException("目标应该是一个目录!");
        }
        for (String zipFile : zipFiles) {
            ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(zipFile)));
            byte[] buffer = new byte[2048];
            int len;
            ZipEntry nextEntry;
            while ((nextEntry = zis.getNextEntry())!=null) {
                String name = nextEntry.getName();
                System.out.println(name);
                BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(file.getPath()+File.separator+ name));
                while ((len=zis.read(buffer))!=-1){
                    bos.write(buffer, 0, len);
                }
                bos.close();
            }
            zis.close();

        }
    }

    public static List<String> getDirectoryFile(File filePath){
        ArrayList<String> list = new ArrayList<>();
        return getDirectoryFile(filePath,list);
    }
    public static List<String> getDirectoryFile(List<String> filePath){
        ArrayList<String> list = new ArrayList<>();
        return getDirectoryFile(filePath.stream().map(File::new).collect(Collectors.toList()),list);
    }

    private static List<String> getDirectoryFile(File filePath, List<String> collectFiles){
        if (filePath.exists()&&filePath.isDirectory()){
            File[] files = filePath.listFiles();
            if (files!=null){
                List<File> directoryFile = getDirectoryFile(files, collectFiles.stream().map(File::new).collect(Collectors.toList()));
                collectFiles.addAll(directoryFile.stream().map(Objects::toString).collect(Collectors.toList()));
            }
        }else {
            collectFiles.add(filePath.toString());
        }
        return collectFiles;
    }
    private static List<String> getDirectoryFile(List<File> filePaths, List<String> collectFiles){
        File[] files = filePaths.toArray(new File[]{});
        List<File> directoryFile = getDirectoryFile(files, collectFiles.stream().map(File::new).collect(Collectors.toList()));
        return directoryFile.stream().map(File::toString).collect(Collectors.toList());
    }

    /**核心递归方法
     * @param filePaths 当前的文件列表
     * @param collectFiles 收集的总目标文件列表
     * @return 所有文件的全路径
     */
    public static List<File> getDirectoryFile(File[] filePaths, List<File> collectFiles){
        for (File filePath : filePaths) {
            if (!filePath.exists()){
                continue;
            }
            if (filePath.isDirectory()){
                File[] files = filePath.listFiles();
                if (files!=null){
                    getDirectoryFile(files,collectFiles);
                }
            }else {
                collectFiles.add(filePath);
            }
        }
        return collectFiles;
    }
}
